﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Sunboxsoft.WinForm
{
    public class Promise
    {
        Queue<Step> _stepQueue = new Queue<Step>();
        Action _finalyCallback;

        public Promise Then(Action success, Action failure = null)
        {
            _stepQueue.Enqueue(new Step() { Success = success, Failure = failure });
            return this;
        }

        public void Run(Action callback = null)
        {
            _finalyCallback = callback;

            this.Resolve();
        }

        public void Resolve()
        {
            if (_stepQueue.Count > 0)
            {
                Step step = _stepQueue.Dequeue();
                if (step.Success != null)
                {
                    //step.Success();
                    step.Success.BeginInvoke(OnAsyncCallback, null);
                }
            }
            else
            {
                return;
            }
            if (_stepQueue.Count == 0 && _finalyCallback!= null)
            {
                //_finalyCallback();
                _finalyCallback.BeginInvoke(OnAsyncCallback, null);
                _finalyCallback = null;
            }
        }

        public void Reject()
        {
            if (_stepQueue.Count > 0)
            {
                Step step = _stepQueue.Dequeue();
                if (step.Failure != null)
                {
                    //step.Failure();
                    step.Failure.BeginInvoke(OnAsyncCallback, null);
                }
            }
            else
            {
                return;
            }
            if (_stepQueue.Count == 0 && _finalyCallback != null)
            {
                //_finalyCallback();
                _finalyCallback.BeginInvoke(OnAsyncCallback, null);
                _finalyCallback = null;
            }
        }

        void OnAsyncCallback(IAsyncResult ar)
        {
        }

        class Step
        {
            public Action Success;
            public Action Failure;
        }
    }
}
